home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 114 / macaddict114.cdr / Software / Internet & Communication / MailSteward.dmg / MailSteward.app / Contents / Resources / domail.pl < prev    next >
Encoding:
Perl Script  |  2005-11-21  |  22.3 KB  |  765 lines

  1. #!/usr/bin/perl
  2. # read and parse unix mailboxes and write a temp file.
  3.  
  4. use File::Find;
  5.  
  6. $append = ">";
  7. $temppath = shift;
  8. $allmbState = shift;
  9. $attachState = shift;
  10. $htmlState = shift;
  11. $trashState = shift;
  12. $mboxState = shift;
  13. $beginDate = shift;
  14. $endDate = shift;
  15. $beginDate =~ /(\d+)-(\d+)-(\d+)/;
  16. $beginYr = $1; $beginMo = $2; $beginDa = $3;
  17. $endDate =~ /(\d+)-(\d+)-(\d+)/;
  18. $endYr = $1; $endMo = $2; $endDa = $3;
  19. undef @attachTypes;
  20. undef @attachFilenames;
  21. undef @attachBlobs;
  22. undef @attachEncodings;
  23. undef @directories;
  24. undef @accounts;
  25. undef %options;
  26. $attachCount = $chunkCount = 0;
  27. %months = (
  28.     "jan","01",
  29.     "feb","02",
  30.     "mar","03",
  31.     "apr","04",
  32.     "may","05",
  33.     "jun","06",
  34.     "jul","07",
  35.     "aug","08",
  36.     "sep","09",
  37.     "oct","10",
  38.     "nov","11",
  39.     "dec","12"
  40.     );
  41.  
  42. #open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!\n";
  43. if ( $mboxState ) {
  44.     while ( $filePath = shift ) {
  45.         open ( TMPFILE, "$append$temppath" ) || print STDERR "problem opening $temppath\n";
  46.  
  47.         #    binmode(TMPFILE, ":utf8");
  48.         print TMPFILE "MAILBOX: $filePath\n";
  49.     $mailbox = $filePath;
  50.     $mailbox =~ s/^.+\/([^\/]+)$/$1/;
  51.         if ( !(open ( INFILE, "<$filePath" )) ) { print STDERR "problem opening $filePath\n"; }
  52.         else {
  53.             read( INFILE,$buf,1000 );
  54.             if ( $buf =~ /\r/ ) {
  55.                 $/ = "\r";
  56.             }
  57.             close INFILE;
  58.             if ( !(open ( INFILE, "<$filePath" )) ) { print STDERR "problem opening $filePath\n"; }
  59.         }
  60.         &parseIt;
  61.         close INFILE;
  62.         close TMPFILE;
  63.         $append = ">>";
  64.     }
  65. } else {
  66.     while ( $account = shift ) {
  67.         push @accounts, $account;
  68.     }
  69.     $options{'wanted'} = \&wanted;
  70.     $options{'no_chdir'} = 1;
  71.     find(\%options, @accounts);
  72.     foreach $dir (@directories) {
  73.         &doDirectory ($dir);
  74.     }
  75. }
  76. #close STDERR;
  77.  
  78. sub wanted {
  79.     local($file) = $File::Find::name;
  80.     if ( $file =~ /Delivered|Drafts|Outbox/i ) { return; }
  81.     if ( !$trashState && $file =~ /Deleted|Junk|Trash/i ) { return; }
  82.     $file = s/^.+\/([^\/]+)$/$1/;
  83.     if ( $file =~ /^\./ ) { return; }
  84.     if ( (-d $File::Find::name) ) {
  85.         push @directories, $File::Find::name;
  86.     }
  87. }
  88.  
  89. sub doDirectory {
  90.     local($targetdir) = @_;
  91.     local(@files);
  92.     opendir(NEXTDIR, "$targetdir") || print STDERR "doDirectory: problem opening $targetdir\n";
  93.     @files = readdir(NEXTDIR);
  94.     closedir NEXTDIR;
  95.     my $modDate = my $year = my $day_of_month = my $month = "";
  96.     foreach $file ( @files ) {
  97.         if ( $file =~ /^\./ ) { next; }
  98.         if ( (-d "$targetdir/$file") ) {
  99.             next;
  100.         }
  101.         $filePath = "$targetdir/$file";
  102.     if ( !$allmbState && $filePath =~ /Mailboxes/i && $filePath !~ /Sent/i ) { next; }
  103.     if ( $filePath =~ /Sent/i && !$allmbState ) {
  104.         $sentOK = 0;
  105.         foreach $myaccount (@accounts) {
  106.         $myaccount =~ s/Mac-//;
  107.         if ( $myaccount eq 'Mailboxes' ) { next; }
  108.         if ( $filePath =~ /$myaccount/ ) {
  109.             $sentOK = 1;
  110.             last;
  111.         }
  112.         }
  113.         if ( !$sentOK ) { next; }
  114.     }
  115.         if ( $file ne 'mbox' && $file !~ /^\d+$/ && $file !~ /\.partial.*$/ && $file !~ /\.emlx/ ) { next; }
  116.     ($modDate) = (stat($filePath))[9];
  117.     ($junk,$junk,$junk,$day_of_month,$month,$year,$junk,$junk,$junk) = localtime($modDate);
  118.     if ( $year < 1900 ) { $year += 1900; }
  119.     while ( length($day_of_month) < 2 ) { $day_of_month = '0' . $day_of_month; }
  120.     while ( length($month) < 2 ) { $month = '0' . $month; }
  121.     $modDate = $year . '-' . $month . '-' . $day_of_month . ' 00:00:00';
  122.     if ( $modDate < $beginDate ) {
  123.         next;
  124.     }
  125.         if ( !(open ( INFILE, "<$filePath" )) ) { print STDERR "problem opening $filePath\n"; }
  126.         open ( TMPFILE, "$append$temppath" ) || print STDERR "problem opening $temppath\n";
  127.  
  128.         #    binmode(TMPFILE, ":utf8");
  129.         $mailbox = $targetdir;
  130.         $mailbox =~ s/\/CachedMessages//;
  131.         $mailbox =~ s/\/Messages//;
  132.         $mailbox =~ s/^.*\/([^\/]+\/[^\/]+)$/$1/;
  133.         $mailbox =~ s/\.mbox$//;
  134.         $mailbox =~ s/\.imapmbox$//;
  135.         $mailbox =~ s/^POP-//;
  136.         &parseIt;
  137.         close TMPFILE;
  138.         $append = ">>";
  139.         close INFILE;
  140.     }
  141. }
  142.  
  143. sub parseIt {
  144.     $body=$mday=$month=$year=$addr=$addr2=$subject=$encoding=$boundary=$disposition=$charset="";
  145.     $content = "text/plain";
  146.     undef @boundarys;
  147.     $attachCount = $chunkCount = 0;
  148.     undef @chunkFiles;
  149.     if ( $filePath =~ /\.partial.*$/ ) { &doChunkFiles; }
  150.     
  151.     while ( <INFILE> ) {
  152. DOIT:
  153.         if ( eof(INFILE) ) {
  154.             if ( $addr ne "" ) {
  155.                 &stuffIt;
  156.             }
  157.             last;
  158.         }
  159.     if ( $year && $mday && $month ) {
  160.         if ( $month < 1 || $month > 12 ) {
  161.             $monthnum = $months{lc $month};
  162.         }
  163.         while (length($month) < 2) { $month = '0' . $month; }
  164.         while (length($mday) < 2) { $mday = '0' . $mday; }
  165.         if ( $year < 100 ) { $year += 1900; }
  166.         $date = $year . "-$monthnum" . "-$mday 00:00:00";
  167.         if ( $date lt $beginDate || $date gt $endDate ) {
  168.         while ( !/^From\s/  && !eof(INFILE) ) {
  169.             $_ = <INFILE>;
  170.         }
  171.                 $body=$mday=$month=$year=$addr=$addr2=$subject=$encoding=$boundary=$disposition=$charset="";
  172.                 $content = "text/plain";
  173.                 undef @boundarys;
  174.                 goto DOIT;
  175.         }
  176.     }
  177.         if ( /Content-Transfer-Encoding: ([^\;]+)/i ) {
  178.             $encoding = $1;
  179.             chomp($encoding);
  180.             next;
  181.         }
  182.         if ( /Content-Disposition: ([^\;]+)/i ) {
  183.             $disposition = $1;
  184.             chomp($disposition);
  185.             next;
  186.         }
  187.         if ( /^Content-type:\s+/i ) {
  188.             &doContent;
  189.             goto DOIT;
  190.         }
  191.         if ( /boundary=.+$/i ) {
  192.             &doBoundary;
  193.             next;
  194.         }
  195.         if ( $boundary ne "" && &checkBoundary ) {
  196.             next;
  197.         }
  198.         if ( /^Date:\s*([A-Za-z]+),\s+([0-9]+)\s+([A-Za-z]+)\s+(\d+)\s+(\d+):(\d+):(\d+)/i && !$year ) {
  199.             $weekday = $1;
  200.             $mday = $2;
  201.             $month = $3;
  202.             $year = $4;
  203.             $hours = $5;
  204.             $min = $6;
  205.             $sec = $7;
  206.         } elsif ( /^Date:\s*([0-9]+)\s+([A-Za-z]+)\s+(\d+)\s+(\d+):(\d+):(\d+)/i && !$year ) {
  207.             $weekday = "";
  208.             $mday = $1;
  209.             $month = $2;
  210.             $year = $3;
  211.             $hours = $4;
  212.             $min = $5;
  213.             $sec = $6;
  214.         } elsif ( /^Date:\s*([A-Za-z]+),\s+([0-9]+)\s+([A-Za-z]+)\s+(\d+)\s+(\d+):(\d+)/i && !$year ) {
  215.             $weekday = $1;
  216.             $mday = $2;
  217.             $month = $3;
  218.             $year = $4;
  219.             $hours = $5;
  220.             $min = $6;
  221.             $sec = '00';
  222.         } elsif ( /^Date:\s*([A-Za-z]+)\s+(\d+),\s+(\d+)\s+(\d+):(\d+):(\d+)/i && !$year ) {
  223.             $weekday = "";
  224.             $month = $1;
  225.             $mday = $2;
  226.             $year = $3;
  227.             $hours = $4;
  228.             $min = $5;
  229.             $sec = $6;
  230.             $month =~ s/^(...).+$/$1/;
  231.         } elsif ( /^Date:\s*([A-Za-z]+)\s+([A-Za-z]+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+[A-Z]+\s+(\d+)/i && !$year ) {
  232. #    Date: Thu Sep 01 10:30:47 PDT 2005
  233.             $weekday = $1;
  234.             $month = $2;
  235.             $mday = $3;
  236.             $hours = $4;
  237.             $min = $5;
  238.             $sec = $6;
  239.             $year = $7;
  240.         } elsif ( /^Date:\s*(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)/i && !$year ) {
  241. # Date: 12/2/2004 8:44:37 AM
  242.             $month = $1;
  243.             $mday = $2;
  244.             $year = $3;
  245.             $hours = $4;
  246.             $min = $5;
  247.             $sec = $6;
  248.         } elsif ( /^Date:\s*([A-Za-z]+)\s+(\d+),\s+([A-Za-z]+)\s+(\d+)\s+(\d+):(\d+):(\d+)/i && !$year ) {
  249. # Date: SAT 03, SEP 2005 23:03:47
  250.             $weekday = $1;
  251.             $mday = $2;
  252.             $month = $3;
  253.             $year = $4;
  254.             $hours = $5;
  255.             $min = $6;
  256.             $sec = $7;
  257.         } elsif ( /^Date:\s\S/i ) {
  258.             if ( !$year ) {
  259.                 $year = 1900;
  260.                 $month = "Jan";
  261.                 $mday = $hours = $min = $sec = '00';
  262.             }
  263.         } elsif ( /filename=\s*([^\;]+)/i ) {
  264.             $filename = $1;
  265.             $filename =~ s/\"//g;
  266.             next;
  267.         } elsif ( /^Subject:\s*(.+)$/i && !$subject ) {
  268.             $subject = $1;
  269.             chomp($subject);
  270.             $_ = <INFILE>;
  271.             while ( $_ =~ /^\s+([^\s].+)$/  && !eof(INFILE) ) {
  272.                 $subject .= " $_";
  273.                 chomp($subject);
  274.                 $_ = <INFILE>;
  275.             }
  276.             goto DOIT;
  277.         } elsif ( /^From:/i && !$addr ) {
  278.             if ( /^From:\s*[^<>]+\s*<([^<>]+)>/i ) {
  279.                 $mailto = $1;
  280.                 $mailto =~ s/\"//g;
  281.                 $mailto =~ s/\s+$//;
  282.                 chomp ( $mailto );
  283.             } elsif ( /^From:\s*([^\"<>]+)/i ) {
  284.                 $mailto = $1;
  285.                 chomp ( $mailto );
  286.             }
  287.             /^From:\s*(.+)$/i;
  288.             $addr = $1;
  289.             chomp($addr);
  290.             $_ = <INFILE>;
  291.             while ( $_ =~ /^\s+([^\s].+)$/  && !eof(INFILE) ) {
  292.                 $addr .= $_;
  293.                 chomp($addr);
  294.                 $_ = <INFILE>;
  295.             }
  296.             goto DOIT;
  297.         } elsif ( /^To:\s*(.+)$/i  && !$addr2 ) {
  298.             $addr2 = $1;
  299.             chomp($addr2);
  300.             $_ = <INFILE>;
  301.         if ( /^CC:\s*(.+)$/i ) {
  302.         $addr2 .= ",$1";
  303.         chomp($addr2);
  304.         $_ = <INFILE>;
  305.         while ( $_ =~ /^\s+([^\s].+)$/  && !eof(INFILE) ) {
  306.             $addr2 .= $_;
  307.             chomp($addr2);
  308.             $_ = <INFILE>;
  309.         }
  310.         goto DOIT;
  311.         }
  312.             while ( $_ =~ /^\s+([^\s].+)$/  && !eof(INFILE) ) {
  313.                 $addr2 .= $_;
  314.                 chomp($addr2);
  315.                 $_ = <INFILE>;
  316.             }
  317.             goto DOIT;
  318.         } elsif ( /^(Received:|Return-Path:)/i ) {
  319.             $_ = <INFILE>;
  320.             while ( !/^[\S]+:/  && !eof(INFILE) ) {
  321.                 $_ = <INFILE>;
  322.             }
  323.             goto DOIT;
  324.         } elsif ( /^[\S]+:/ && !/^http:/ && $body eq "" ) {
  325.             $_ = <INFILE>;
  326.             while ( /^\s+([^\s].+)$/  && !eof(INFILE) ) {
  327.                 if ( /filename=\s*([^\;]+)/i ) {
  328.                     $filename = $1;
  329.                     $filename =~ s/\"//g;
  330.                 }
  331.                 $_ = <INFILE>;
  332.             }
  333.             goto DOIT;
  334.         } elsif ( /^X-.+:/ ) { next; }
  335.     elsif ( /charset=([^\;]+)/i ) {
  336.         $charset = $1;
  337.         $charset =~ s/^\"//;
  338.         $charset =~ s/\"$//;
  339.         chomp($charset);
  340.         next;
  341.     } elsif ( /\s+id\s\d/ ) { next; }
  342.     elsif ( /^\d+\s*$/ && $body eq "" ) { next; }
  343.     elsif ( /^\<\?xml / ) {
  344.         while ( <INFILE> ) {
  345.         if ( /\<\/dict\>/ ) {
  346.             $_ = <INFILE>;
  347.             last;
  348.         }
  349.         if ( /\<key\>original-mailbox\<\/key\>/ ) {
  350.             $_ = <INFILE>;
  351.             if ( /Outbox/ ) { next; }
  352.             $mailbox = $_;
  353.             $mailbox =~ s/\<string\>//;
  354.             $mailbox =~ s/\<\/string\>//;
  355.             $mailbox =~ s/[^:]+:\/+//;
  356.             $mailbox =~ s/\%20/ /g;
  357.             $mailbox =~ s/\%40/\@/g;
  358.             chomp($mailbox);
  359.         }
  360.         }
  361.         goto DOIT;
  362.     } elsif ( /^From\s/ || eof(INFILE)) {
  363.             if ( $addr ne "" ) {
  364.                 &stuffIt;
  365.             }
  366.             while ( <INFILE> ) {
  367.                 if ( !/^[\S]+:/ ) { next; }
  368.                 $body=$mday=$month=$year=$addr=$addr2=$subject=$encoding=$boundary=$disposition=$charset="";
  369.                 $content = "text/plain";
  370.                 undef @boundarys;
  371.                 goto DOIT;
  372.             }
  373.         } else {
  374.             if ( $content =~ /text\/plain/i && $disposition !~ /attachment/i ) {
  375.                 if ( /^content-.+:\s/i ) { next; }
  376.                 if ( $encoding =~ /quoted-printable/i ) {
  377.                     $body .= &decode_qp($_);
  378.                 } elsif ( $encoding =~ /base64/i ) {
  379.                     $body .= &decode_base64($_);
  380.                 } else {
  381.                     $body .= $_;
  382.                 }
  383.                 next;
  384.             } elsif ( $content =~ /multipart|application\/applefile/i ) {
  385.                 next;
  386.             } else {
  387.                 if ( $attachState || $htmlState ) {
  388.                     &doAttachment;
  389.                     goto DOIT;
  390.                 }
  391.                 next;
  392.             }
  393.         }
  394.     }
  395. }
  396.  
  397. sub doBoundary {
  398.     if ( /boundary=(.+)$/i ) {
  399.         $boundary = $1;
  400.     }
  401.     chomp($boundary);
  402.     $boundary =~ s/\"//g;
  403.     $boundary =~ s/(\W)/\\$1/g;
  404.     push @boundarys, $boundary;
  405. }
  406.  
  407. sub checkBoundary {
  408.     foreach $junk (@boundarys) {
  409.         if ( $junk ne "" && /$junk/i ) {
  410.             return 1;
  411.         }
  412.     }
  413.     return 0;
  414. }
  415.  
  416. sub doContent {
  417.     $disposition = "";
  418.     if ( /^Content-type:\s+([^\;]+)/i ) {
  419.         $content = $1;
  420.     }
  421.     chomp($content);
  422.     if ( /boundary=.+$/i ) {
  423.         &doBoundary;
  424.     }
  425.     if ( /name=([^\;]+)/ ) {
  426.         $filename = $1;
  427.         $filename =~ s/\"//g;
  428.     }
  429.     if ( /filename=([^\;]+)/i ) {
  430.         $filename = $1;
  431.         $filename =~ s/^\"//;
  432.         $filename =~ s/\"$//;
  433.     }
  434.     if ( /charset=([^\;]+)/i ) {
  435.         $charset = $1;
  436.         $charset =~ s/^\"//;
  437.         $charset =~ s/\"$//;
  438.         chomp($charset);
  439.     }
  440.     $_ = <INFILE>;
  441.     while ( /^\s+[\S].+$/  && !eof(INFILE) ) {
  442.         if ( /boundary=.+$/i ) {
  443.             &doBoundary;
  444.         }
  445.         if ( /name=([^\;]+)/ ) {
  446.             $filename = $1;
  447.             $filename =~ s/\"//g;
  448.         }
  449.         if ( /filename=([^\;]+)/i ) {
  450.             $filename = $1;
  451.             $filename =~ s/^\"//;
  452.             $filename =~ s/\"$//;
  453.         }
  454.         if ( /charset=([^\;]+)/i ) {
  455.             $charset = $1;
  456.             $charset =~ s/^\"//;
  457.             $charset =~ s/\"$//;
  458.             chomp($charset);
  459.         }
  460.         $_ = <INFILE>;
  461.     }
  462.  
  463. #    print STDERR "\nFROM:$addr\nTO:$addr2\nSUBJECT:$subject\nDATE:$date\nMAILTO:$mailto\nTYPE:$content\n";
  464. }
  465.  
  466. sub doAttachment {
  467.     $blob = "";
  468.     while ( ($boundary eq "" || !&checkBoundary) && !eof(INFILE) && !/^From\s/ ) {
  469.         if ( /Content-Transfer-Encoding:\s*([^\;]+)/i ) {
  470.             $encoding = $1;
  471.             $_ = <INFILE>;
  472.             next;
  473.         } elsif ( /^Content-type:\s+/i ) {
  474.             &doContent;
  475.             if ( $content =~ /multipart/i ) { return; }
  476.             next;
  477.         } elsif ( /filename=([^\;]+)/i ) {
  478.             $filename = $1;
  479.             $filename =~ s/^\"//;
  480.             $filename =~ s/\"$//;
  481.             $_ = <INFILE>;
  482.             next;
  483.         } elsif ( /boundary=.+$/i ) {
  484.             &doBoundary;
  485.             $_ = <INFILE>;
  486.             next;
  487.         } elsif ( /^\s*$/ ) {
  488.             $_ = <INFILE>;
  489.             while ( ($boundary eq "" || !checkBoundary) && !eof(INFILE) && !/^From\s/ ) {
  490.                 if ( /^[\S]+:\s/ && $content !~ /html/i ) {
  491.                     return;
  492.                 }
  493.                 if ( /boundary=.+$/i ) {
  494.                     &doBoundary;
  495.                     $_ = <INFILE>;
  496.                     next;
  497.                 }
  498.                 $blob .= $_;
  499.                 $_ = <INFILE>;
  500.             }
  501.             next;
  502.         } else { $_ = <INFILE>; next; }
  503.     }
  504.     if ( $content eq "" ) { return; }
  505.     chomp($filename);
  506.     if ( $filename eq "" ) {
  507.         $filename = "attachment" . $attachCount;
  508.     }
  509.     if ( $filename =~ /win\.dat/i ) {
  510.     } elsif ( $content =~ /html/i && $filename !~ /\.htm/i ) {
  511.         $filename .= '.html';
  512.     } elsif ( $content =~ /text\/enriched/i && $filename !~ /\.etf$/i ) {
  513.         $filename .= '.etf';
  514.     } elsif ( $content =~ /msword/i && $filename !~ /\.doc$/i ) {
  515.         $filename .= '.doc';
  516.     } elsif ( $content =~ /pdf/i && $filename !~ /\.pdf$/i ) {
  517.         $filename .= '.pdf';
  518.     } elsif ( $content =~ /jpeg/i && $filename !~ /\.jpg$/i && $filename !~ /\.jpeg$/i ) {
  519.         $filename .= '.jpg';
  520.     } elsif ( $content =~ /gif/i && $filename !~ /\.gif$/i ) {
  521.         $filename .= '.gif';
  522.     } elsif ( $content =~ /tiff/i && $filename !~ /\.tif/i ) {
  523.         $filename .= '.tiff';
  524.     }
  525.     chomp($encoding);
  526.     if ( $filePath =~ /\.partial.*$/ ) { &doChunk; }
  527.     if ( $blob !~ /^\s*$/ && $blob ne "" ) {
  528.         $charset = lc($charset);
  529.         $charset =~ s/\s+$//;
  530.         $charset =~ s/^\s+//;
  531.     
  532.         if ( $content =~ /html|enriched/i && !$htmlState ) {
  533.             $filename = $content = "";
  534.             return;
  535.         }
  536.         if ( $content !~ /html|enriched/i && !$attachState ) {
  537.             $filename = $content = "";
  538.             return;
  539.         }
  540.         if ( $encoding =~ /quoted-printable/i ) {
  541.             $blob = &decode_qp($blob);
  542.         }
  543.         $attachTypes[$attachCount] = $content;
  544.         $attachFilenames[$attachCount] = $filename;
  545.         $attachEncodings[$attachCount] = $encoding;
  546.         $attachBlobs[$attachCount] = $blob;
  547.         $attachCount++;
  548.     }
  549.     $filename = $content = "";
  550.     return;
  551. }
  552.  
  553. sub doChunkFiles {
  554.     my $targetdir = $filePath;
  555.     $targetdir =~ s/\/([^\/]+)\.partial.*$//;
  556.     my $file = $1;
  557.     opendir(TARGETDIR, "$targetdir") || print STDERR "problem opening $targetdir\n";
  558.     @chunkFiles = sort grep (/$file\.\d/, readdir(TARGETDIR));
  559.     closedir TARGETDIR;
  560. }
  561.  
  562. sub doChunk {
  563.     $chunkCount++;
  564.     if ( !$htmlState && $body ne "" ) {
  565.         $blob = "";
  566.         return;
  567.     }
  568.     if ( !$attachState && $content !~ /html|enriched/ ) {
  569.         $blob = "";
  570.         return;
  571.     }
  572.     my $targetdir = $filePath;
  573.     $targetdir =~ s/\/([^\/]+)\.partial.*$//;
  574.     my $file = $chunkFiles[$chunkCount-1];
  575.     if ( $file eq "" ) { return; }
  576.     if ( !(open ( CHUNK, "<$targetdir/$file" )) ) { print STDERR "problem opening $targetdir/$file\n"; return; }
  577.     $tmp = $/;
  578.     undef $/;
  579.     $blob = <CHUNK>;
  580.     $/ = $tmp;
  581.     close CHUNK;
  582. }
  583.  
  584. sub stuffIt {
  585.     my $i = 0;
  586.     if ( $month < 1 || $month > 12 ) {
  587.         $month = $months{lc $month};
  588.     }
  589.     while (length($month) < 2) { $month = '0' . $month; }
  590.     while (length($mday) < 2) { $mday = '0' . $mday; }
  591.     if ( $year < 100 ) { $year += 1900; }
  592.     $date = $year . "-$month" . "-$mday" . " $hours:$min:$sec";
  593.     if ( $year < $beginYr ) { goto DONE; }
  594.     if ( $year == $beginYr && $month < $beginMo ) { goto DONE; }
  595.     if ( $year == $beginYr && $month == $beginMo && $mday < $beginDa ) { goto DONE; }
  596.     if ( $year > $endYr ) { goto DONE; }
  597.     if ( $year == $endYr && $month > $endMo ) { goto DONE; }
  598.     if ( $year == $endYr && $month == $endMo && $mday > $endDa ) { goto DONE; }
  599.     $addr =~ s/\"//g;
  600.     $addr2 =~ s/\"//g;
  601.     $body =~ s/\©\;/¬©/g;
  602.     $charset = lc($charset);
  603.     $charset =~ s/\s+$//;
  604.     $charset =~ s/^\s+//;
  605.     
  606.     if ( 0 ) {
  607. #    if ( $charset ne "" && $charset !~ /us-ascii/i && $charset !~ /iso-8859-1/i && $charset !~ /utf-8/i ) {
  608.         $tmp = $/;
  609.         undef $/;
  610.         open ( BODY, "< :encoding($charset)", \$body) || print STDERR "problem opening body with $charset\n";
  611.         $body = <BODY>;
  612.         close BODY; 
  613.         $subject =~ s/=?ISO-8859-\d?Q?//ig;
  614.         open ( SUBJECT, "< :encoding($charset)", \$subject) || print STDERR "problem opening subject with $charset\n";
  615.         $subject = <SUBJECT>;
  616.         $/ = $tmp;
  617.         close SUBJECT;
  618.     }
  619.     $addr = &myDecode($addr);
  620.     $addr2 = &myDecode($addr2);
  621.     if ( $subject =~ /=\?UTF-8\?B\?([^\?]+)\?=/i ) {
  622.         $subject = $1;
  623.         $subject = decode_base64($subject);
  624.     }
  625.     $subject = &myDecode($subject);
  626.     $body = &myDecode($body);
  627.  
  628.     print TMPFILE "MAILBOX: $mailbox\n";
  629.     print TMPFILE "\nFROM:$addr\nTO:$addr2\nSUBJECT:$subject\nDATE:$date\nMAILTO:$mailto\nBODY:$body\nENDOFBODY:\n";
  630.     if ( ($attachState || $htmlState) && $attachCount ) {
  631.         for ( $i=0; $i<$attachCount; $i++ ) {
  632.             $attachType = $attachTypes[$i];
  633.             print TMPFILE "ATTACH:\nTYPE:$attachType\nFILENAME:$attachFilenames[$i]\nENCODING:$attachEncodings[$i]\nBLOB:\n$attachBlobs[$i]\nENDATTACH:\n";
  634.         }
  635.         if ( $i ) { print TMPFILE "ENDATTACHMENTS:\n"; }
  636.     }
  637.   DONE:
  638.     undef @attachTypes;
  639.     undef @attachFilenames;
  640.     undef @attachBlobs;
  641.     undef @attachEncodings;
  642.     $attachCount = 0;
  643. }
  644.  
  645. sub decode_qp ($) {
  646.     my $res = shift;
  647.     $res =~ s/\r\n/\n/g;            # normalize newlines
  648.     $res =~ s/[ \t]+\n/\n/g;        # rule #3 (trailing space must be deleted)
  649.     $res =~ s/[ \t]+\r/\r/g;        # rule #3 (trailing space must be deleted)
  650.     $res =~ s/=\n//g;               # rule #5 (soft line breaks)
  651.     $res =~ s/=\r//g;               # rule #5 (soft line breaks)
  652.     $res = &myDecode($res);
  653.     $res =~ s/=([\da-fA-F]{2})/pack("C", hex($1))/ge;
  654.     return $res;
  655. }
  656.  
  657. sub myDecode ($) {
  658. #    =?UTF-8?B?ZUJheSBJbnZvaWNlIGZvciBXZWRuZXNkYXksIEF1Z3VzdCAzMSwgMjAwNQ==?=
  659.     my $res = shift;
  660.     $res =~ s/=\?ISO-8859-\d+\?Q\?([^\?]+)\?=/$1/ig;
  661.     $res =~ s/=E2=80=94/--/ig;
  662.     $res =~ s/=a0/ /ig;
  663.     $res =~ s/=a9/¬©/ig;
  664.     $res =~ s/=b9/'/ig;
  665.     $res =~ s/=e9/√©/ig;
  666.     $res =~ s/=f4/√¥/ig;
  667.     $res =~ s/=e0/√†/ig;
  668.     $res =~ s/=e7/√ß/ig;
  669.     $res =~ s/=3d/=/ig;
  670.     $res =~ s/=a3/¬£/ig;
  671.     $res =~ s/=ae/¬Æ/ig;
  672.     $res =~ s/=e1/√°/ig;
  673.     $res =~ s/=a2/¬¢/ig;
  674.     $res =~ s/=e2/√¢/ig;
  675.     $res =~ s/=e3/√£/ig;
  676.     $res =~ s/=e4/√§/ig;
  677.     $res =~ s/=e5/√•/ig;
  678.     $res =~ s/=e6/√¶/ig;
  679.     $res =~ s/=e8/√®/ig;
  680.     $res =~ s/=ea/√™/ig;
  681.     $res =~ s/=eb/√´/ig;
  682.     $res =~ s/=ec/√¨/ig;
  683.     $res =~ s/=ed/√≠/ig;
  684.     $res =~ s/=ee/√Æ/ig;
  685.     $res =~ s/=ef/√Ø/ig;
  686.     $res =~ s/=f0/√∞/ig;
  687.     $res =~ s/=f1/√±/ig;
  688.     $res =~ s/=f2/√≤/ig;
  689.     $res =~ s/=f3/√≥/ig;
  690.     $res =~ s/=f5/√µ/ig;
  691.     $res =~ s/=f6/√∂/ig;
  692.     $res =~ s/=f7/√∑/ig;
  693.     $res =~ s/=f8/√∏/ig;
  694.     $res =~ s/=f9/√π/ig;
  695.     $res =~ s/=fa/√∫/ig;
  696.     $res =~ s/=fb/√ª/ig;
  697.     $res =~ s/=fc/√º/ig;
  698.     $res =~ s/=c0/√Ä/ig;
  699.     $res =~ s/=c1/√Å/ig;
  700.     $res =~ s/=c2/√Ç/ig;
  701.     $res =~ s/=c3/√É/ig;
  702.     $res =~ s/=c4/√Ñ/ig;
  703.     $res =~ s/=c5/√Ö/ig;
  704.     $res =~ s/=c6/√Ü/ig;
  705.     $res =~ s/=c7/√á/ig;
  706.     $res =~ s/=c8/√à/ig;
  707.     $res =~ s/=c9/√â/ig;
  708.     $res =~ s/=ca/√ä/ig;
  709.     $res =~ s/=cb/√ã/ig;
  710.     $res =~ s/=cc/√å/ig;
  711.     $res =~ s/=cd/√ç/ig;
  712.     $res =~ s/=ce/√é/ig;
  713.     $res =~ s/=cf/√è/ig;
  714.     $res =~ s/=d0/√ê/ig;
  715.     $res =~ s/=d1/√ë/ig;
  716.     $res =~ s/=d2/√í/ig;
  717.     $res =~ s/=d3/√ì/ig;
  718.     $res =~ s/=d4/√î/ig;
  719.     $res =~ s/=d5/√ï/ig;
  720.     $res =~ s/=d6/√ñ/ig;
  721.     $res =~ s/=d7/√ó/ig;
  722.     $res =~ s/=d8/√ò/ig;
  723.     $res =~ s/=d9/√ô/ig;
  724.     $res =~ s/=da/√ö/ig;
  725.     $res =~ s/=db/√õ/ig;
  726.     $res =~ s/=dc/√ú/ig;
  727.     $res =~ s/=dd/√ù/ig;
  728.     $res =~ s/=de/√û/ig;
  729.     $res =~ s/=df/√ü/ig;
  730.     $res =~ s/=09/\t/g;
  731.     $res =~ s/=20=\n/\n/g;
  732.     $res =~ s/=20=\r/\r/g;
  733.     $res =~ s/=20\n/\n/g;
  734.     $res =~ s/=20\r/\r/g;
  735.     $res =~ s/\s=\n/\n/g;
  736.     $res =~ s/\s=\r/\r/g;
  737.     return $res;
  738. }
  739.  
  740. sub decode_base64 ($) {
  741.     local($^W) = 0;
  742.     use integer;
  743.  
  744.     my $str = shift;
  745.     $str =~ tr|A-Za-z0-9+=/||cd;
  746.     if (length($str) % 4) {
  747.     }
  748.     $str =~ s/=+$//;
  749.     $str =~ tr|A-Za-z0-9+/| -_|;
  750.     return "" unless length $str;
  751.  
  752.     my $uustr = '';
  753.     my ($i, $l);
  754.     $l = length($str) - 60;
  755.     for ($i = 0; $i <= $l; $i += 60) {
  756.         $uustr .= "M" . substr($str, $i, 60);
  757.     }
  758.     $str = substr($str, $i);
  759.     if ($str ne "") {
  760.         $uustr .= chr(32 + length($str)*3/4) . $str;
  761.     }
  762.     return unpack ("u", $uustr);
  763. }
  764.  
  765.